package com.woorigil.social.worker;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.woorigil.social.domain.ApplicationService;
import com.woorigil.social.domain.ProviderCode;
import com.woorigil.social.domain.category.CategoryMapperFactory;
import com.woorigil.social.domain.deal.Deal;
import com.woorigil.social.domain.deal.DealDao;
import com.woorigil.social.domain.deal.DealListDocument;
import com.woorigil.social.domain.deal.ManageStatus;
import com.woorigil.social.domain.history.WorkHistory;
import com.woorigil.social.domain.history.WorkHistoryDao;
import com.woorigil.social.domain.point.DealPoint;
import com.woorigil.social.domain.point.DealPointDao;
import com.woorigil.social.parser.XmlParser;

@Component
public class DealDataLoadWorker {
	public static final String WORK_NAME = "DEAL_LOAD";
	@Autowired List<XmlParser> parsers;
	@Autowired DealDao dealDao;
	@Autowired CategoryMapperFactory categoryMapperFactory;
	@Autowired DealPointDao dealPointDao;
	@Autowired WorkHistoryDao workHistoryDao;
	@Autowired ApplicationService applicationInitService;

	public void execute() throws Exception {
		if (parsers == null) {
			return;
		}

		dealPointDao.updateStatus(ManageStatus.D);
		for (XmlParser parser : parsers) {
			System.out.println("parser start : " + parser.getProviderCode());
			try {
				InputStream is = new FileInputStream(parser.getSourcePath());
				Reader reader = new BufferedReader(new InputStreamReader(is, parser.getCharsetName()));
				DealListDocument dealListDocument = parser.parse(reader);
				
				dealDao.updateStatus(parser.getProviderCode(), ManageStatus.D);
				
				for (Deal newDeal : dealListDocument.getDeals()) {
					Deal beforeDeal = dealDao.selectByMetaId(newDeal.getProviderCode(), newDeal.getMetaId());
					int dealId = dealProcess(beforeDeal, newDeal, parser.getProviderCode());
					dealPointProcess(beforeDeal, newDeal, dealId);
				}
				
				dealDao.deleteByManageStatus(parser.getProviderCode(), ManageStatus.D);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		dealPointAfterProcess();
		workHistoryDao.insert(new WorkHistory(WORK_NAME, new Date()));
		applicationInitService.menuInitialize();
	}

	private int dealProcess(Deal beforeDeal, Deal newDeal, ProviderCode providerCode) {
		int dealId = 0;

		if (beforeDeal != null) {
			dealId = beforeDeal.getId();
			newDeal.setId(dealId);
			dealDao.update(newDeal);
		} else {
			dealId = dealDao.insert(newDeal);
			newDeal.setId(dealId);
		}
		return dealId;
	}

	private void dealPointProcess(Deal beforeDeal, Deal newDeal, int dealId) {
		DealPoint beforeDealPoint = dealPointDao.select(dealId);
		if (beforeDealPoint != null) {
			int saleAverage = computeSaleAverage(beforeDeal, newDeal, beforeDealPoint);
			DealPoint newDealPoint = new DealPoint(dealId, saleAverage, ManageStatus.S);
			dealPointDao.update(newDealPoint);
		} else {
			dealPointDao.insert(new DealPoint(dealId, 0, ManageStatus.S));
		}
	}

	private void dealPointAfterProcess() {
		dealPointDao.deleteByManageStatus(ManageStatus.D);
	}

	private int computeSaleAverage(Deal beforeDeal, Deal newDeal, DealPoint dealPoint) {
		int beforeNowCount = (beforeDeal == null)? 0 : beforeDeal.getNowCount();
		int saleCount = newDeal.getNowCount() - beforeNowCount;
		return saleCount * newDeal.getSalesPrice();
	}
}
